#include <Arduino.h>
#include <math.h>
#include "painlessMesh.h"

#define MQ2pin 0
#define MESH_PREFIX "LittleCoke"
#define MESH_PASSWORD "123456hello"
#define MESH_PORT 5555

#define ESP32_NODE 3316138365
#define ESP32C3_NODE 2030530093
#define ESP32S3_NODE 412166304

painlessMesh mesh;

Scheduler userScheduler;

// 任务函数声明
void sendMessage();
void readSmoke();

// 任务：定期发送数据
Task taskSendMessage(TASK_SECOND * 3, TASK_FOREVER, &sendMessage);
// 任务：定期读取温湿度数据
Task taskReadSmoke(TASK_SECOND * 2, TASK_FOREVER, &readSmoke);

float sensorValue,Voltage,ppm;  //variable to store sensor value

// 读取Smoke数据的任务
void readSmoke() {
	sensorValue = analogRead(MQ2pin); // read analog input pin 0
  	Voltage = sensorValue / 4095.0 * 3.3;
  	ppm = pow(11.5248*35.9*Voltage/(25.5-5.1*Voltage),1.0/0.6549);
	Serial.println("Sensor Value: " + String(sensorValue) + " | Smoke concentration: " + String(ppm) + " ppm");
  }

// 发送数据的任务， ESP32C3 负责向 ESP32 发送烟雾浓度数据
void sendMessage() {
	String msg = "ESP32C3 Node ";
	msg += mesh.getNodeId();
	msg += " | Smoke concentration: " + String(ppm, 2) + "ppm";
	mesh.sendSingle(ESP32_NODE, msg);
	taskSendMessage.setInterval(TASK_SECOND * 1);
  }
  
  // 其他回调函数
  void receivedCallback(uint32_t from, String &msg) {
	Serial.printf("Received from %u: %s\n", from, msg.c_str());
  }
  
  void newConnectionCallback(uint32_t nodeId) {
	Serial.printf("New Connection: nodeId = %u\n", nodeId);
  }
  
  void changedConnectionCallback() {
	Serial.println("Connections changed");
  }
  
  void nodeTimeAdjustedCallback(int32_t offset) {
	Serial.printf("Time adjusted: Offset = %d\n", offset);
  }

void setup() {
	Serial.begin(115200); // sets the serial port to 9600
	mesh.setDebugMsgTypes(ERROR | STARTUP);
	mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
	mesh.onReceive(&receivedCallback);
	mesh.onNewConnection(&newConnectionCallback);
	mesh.onChangedConnections(&changedConnectionCallback);
	mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);

	// 添加任务到调度器
	userScheduler.addTask(taskSendMessage);
	userScheduler.addTask(taskReadSmoke);
	
	taskSendMessage.enable();
	taskReadSmoke.enable();
}

void loop() {
	mesh.update();
}